package com.hc.controller;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hc.common.bean.*;
import com.hc.domain.*;
import com.hc.ex.GlobalException;
import com.hc.listener.ProjExcelListener;
import com.hc.common.oss.AliOSSUtil;
import com.hc.query.SearchVO;
import com.hc.res.*;
import com.hc.service.*;
import com.hc.trans.AuthorTrans;
import com.hc.trans.ProjTrans;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName:ProjController
 * @Author:吴肖扬
 * @Date：2021/11/20 上午 11:23
 * @Describe：
 */
@Slf4j
@Controller
@SuppressWarnings("all")
@RequestMapping("/proj")
public class ProjController {
    @Resource
    private ProjService projService;
    @Resource
    private ProjAuthorService projAuthorService;
    @Resource
    private ProjCategoryService projCategoryService;
    @Resource
    private ProjTechService projTechService;
    @Resource
    private CategoryService categoryService;
    @Resource
    private AuthorService authorService;
    @Resource
    private TechnologyService technologyService;
    @Resource
    private ProjExcelListener projExcelListener;
    /**
     * 删除项目
     *
     * @param id
     * @param mav
     * @return
     */
    @ResponseBody
    @DeleteMapping("/removeById/{id}")
    public Result removeById(@PathVariable("id") Long[] id, ModelAndView mav) {
        //删除成功的数量
        int deleteRes = 0;
        //遍历需要删除的项目id数组
        for (int i = 0; i < id.length; i++) {
            //成功删除一次，成功数量加1
            deleteRes += projService.changeStateToDelete(id[i]);
        }
        //删除成功的个数和需要删除的个数相同，则删除成功
        if (deleteRes == id.length) {
            return ResultUtil.success().setMsg("删除成功");
        } else {
            return ResultUtil.success().setMsg("删除失败");
        }
    }

    /**
     * 项目管理列表
     * @param pageNum
     * @param pageSize
     * @return
     */
    @GetMapping("/getProjByCondition/{pageNum}/{pageSize}")
    public ModelAndView getProjByCondition(
            @PathVariable("pageNum") Integer pageNum,
            @PathVariable("pageSize") Integer pageSize,
            SearchVO searchVO,
            @RequestParam(value = "status",defaultValue = "0") Integer status,
            ModelAndView mav) {
        // 分页查询
        Page<Proj> objects = PageHelper.startPage(pageNum, 10);
        projService.selectByName(searchVO.getSearchValue(),status);
        List<Proj> result = objects.getResult();
        // 数据类型转换
        List<ProjListItemDTO> projListItemDTOS = ProjTrans.MAPPER.projList2ProjListItemDTOList(result);
        for (ProjListItemDTO projListItemDTO : projListItemDTOS) {
            List<AuthorListDTO> authorListDTOS = new ArrayList<>();
            List<Integer> projAuthorIds = projAuthorService.getProjAuthorIds(projListItemDTO.getId());
            // 获取作者信息
            for (Integer projAuthorId : projAuthorIds) {
                AuthorListDTO authorListDTO = AuthorTrans.MAPPER.author2AuthorListDTO(authorService.selectByPrimaryKey(projAuthorId.longValue()));
                authorListDTOS.add(authorListDTO);
            }
            projListItemDTO.setAuthorListDTOS(authorListDTOS);
            // 让简介短一点
            projListItemDTO.setInfo(projListItemDTO.getInfo().substring(0, 25)+".....");
        }
        //分页请求路径
        PageBean<ProjListItemDTO> pageBean = new PageBean<>();
        pageBean.setResult(projListItemDTOS);
        pageBean.setPageSize(objects.getPageSize());
        pageBean.setPageNum(objects.getPageNum());
        pageBean.setTotal(objects.getTotal());
        pageBean.setPages(objects.getPages());
        pageBean.setUrl("proj/getProjByCondition");
        mav.addObject("pageBean", pageBean);
        mav.addObject("title", "项目列表");
        mav.addObject("searchValue",searchVO.getSearchValue());
        mav.setViewName("proj/list");
        return mav;
    }

    /**
     * 根据ID查看项目全信息包括作者、分类、技术
     * @param id  项目id
     * @param cid
     * @return
     */
    @GetMapping("/getProjInfoById/{id}/{cid}")
    public ModelAndView getProjInfoById(@PathVariable("id") int id,
                                        @PathVariable("cid") int cid) {
        ModelAndView modelAndView = new ModelAndView();
        Proj proj = projService.getProjInfoById(id, cid);
        modelAndView.addObject("proj", proj);
        modelAndView.addObject("title", "项目详细信息");
        return modelAndView;
    }

    /**
     * 修改头像
     */
    @ResponseBody
    @PostMapping("/updateAvatar")
    public Result updateAvatar(@RequestParam("avatar") MultipartFile multipartFile,
                               Long id) {
        String avatarUrl = null;
        try {
            avatarUrl = AliOSSUtil.upload(multipartFile);
        } catch (IOException e) {
            throw new GlobalException(408, "图片上传到图片服务器出错");
        }
        Proj proj = Proj.builder()
                .id(id)
                .img(avatarUrl)
                .build();

        projService.updateByPrimaryKeySelective(proj);

        return ResultUtil.success().setMsg(avatarUrl);
    }

    /**
     * 根据ID查看项目全信息包括作者、分类、技术
     *
     * @param id  项目id
     * @return
     */
    @GetMapping("/getProjById/{id}")
    public ModelAndView getProjById(@PathVariable("id") Long id ,ModelAndView mav
            ,String z){
        ProjsDTO projsDTO = projService.selectAllPrimaryKey(id);
        List<Category> categoryList = categoryService.getCategoryByCondition();

        List<Technology> technologyList=technologyService.getTechnologyByCondition();
        mav.addObject("projInfo",projsDTO);
        if(z==null||"".equals(z)) {
            mav.setViewName("proj/detail");
        }else {
            mav.addObject("categoryList", categoryList);
            mav.addObject("technologyList",technologyList);
            mav.setViewName("proj/update");
        }
        return mav;
    }

    /**
     * 修改项目信息
     * @param proj
     * @param categoryName
     * @param technologyName
     * @param authorName
     * @param id
     * @param modelAndView
     * @return
     */
    @PostMapping("/updateProj/{id}")
    public String updateProj(Proj proj,
                             String[] categoryName,
                             String[] technologyName,
                             String authorName,
                             @PathVariable("id") Long id,
                             ModelAndView modelAndView){
        int update = projService.updateByPrimaryKeySelective(proj);
        if (update==1){
            // 1.获取中间表ID
            List<Long> ptIds = projTechService.selectIdByPid(proj.getId());
            List<Long> projCids = projCategoryService.selectIdsByProjId(proj.getId());
            List<Integer> projAuthorIds = projAuthorService.getProjAuthorIds(proj.getId());
            // 2.删除当前中间表
            if (ptIds.size()>0){
                for (Long ptId : ptIds) {
                    projTechService.deleteByPrimaryKey(ptId);
                }
            }
            if (projCids.size()>0){
                for (Long projCid : projCids) {
                    projCategoryService.deleteByPrimaryKey(projCid);
                }
            }
            if (projAuthorIds.size()>0){
                for (Integer projAuthorId : projAuthorIds) {
                    projAuthorService.deleteByPrimaryKey(projAuthorId.longValue());
                }
            }
            // 3.获取新数据的ID
            List<Long> techIds = technologyService.selectIdsByName(technologyName);
            List<Long> cateIds = categoryService.selectIdsByName(categoryName);
            // 处理获取作者ID
            String substring = authorName.substring(1, authorName.length() - 1);
            String[] split = substring.split(",");
            // 处理原有作者和新作者
            List<String> oldName = new ArrayList<>();
            List<String> newName = new ArrayList<>();
            for (String s : split) {
                String trim = s.trim();
                String nickname = authorService.selectByName(trim).getNickname();
                if (nickname != null) {
                    oldName.add(nickname);
                }else {
                    newName.add(trim);
                }
            }
            List<Long> authorIds = authorService.selectAuthorIdsByName(oldName.stream().toArray(String[]::new));
            // 3.重新添加中间表
            for (Long techId : techIds) {
                projTechService.insert(new ProjTech(proj.getId(), techId));
            }
            for (Long cateId : cateIds) {
                projCategoryService.insert(new ProjCategory(proj.getId(),cateId));
            }
            if (authorIds.size()>0){
                for (Long authorId : authorIds) {
                    projAuthorService.insert(new ProjAuthor(proj.getId(), authorId));
                }
            }
            for (String s : newName) {
                Author build = Author.builder().nickname(s).build();
                authorService.insert(build);
                projAuthorService.insert(new ProjAuthor(proj.getId(),build.getId()));
            }
        }
        return "user/index";
    }

    /**
     * 根据主键删除项目
     * @param id
     * @return
     */
    @DeleteMapping("/deleteProjById/{id}")
    public Result deleteById(@PathVariable("id") long id) {
        int i = projService.deleteByPrimaryKey(id);
        if (i == 1) {
            return ResultUtil.success().setMsg("删除成功！");
        } else {
            return ResultUtil.fail().setMsg("删除失败！");
        }
    }

    /**
     * 添加项目,并添加三张中间表
     *
     * @param proj
     * @return
     */
    @PostMapping("/addProj")
    public ModelAndView addProj(Proj proj,
                                String[] categoryName,
                                String[] technologyName,
                                String authorName,
                                @RequestPart MultipartFile picture,
                                ModelAndView modelAndView) {
        if (!picture.isEmpty()){
            String avatarUrl = null;
            try {
                avatarUrl = AliOSSUtil.upload(picture);
                proj.setImg(avatarUrl);
            } catch (IOException e) {
                throw new GlobalException(408, "图片上传到图片服务器出错");
            }
        }
        // 插入项目
        int insert = projService.insert(proj,categoryName,technologyName,authorName);
        String[] split = authorName.split(",");
        List<Long> authorIds = authorService.selectAuthorIdsByName(split);
        if (authorIds.size()>0){
            for (Long authorId : authorIds) {
                projAuthorService.insert(new ProjAuthor(proj.getId(), authorId));
            }
        }else {
            for (String s : split) {
                Author build = Author.builder().nickname(s).build();
                authorService.insert(build);
                projAuthorService.insert(new ProjAuthor(proj.getId(), build.getId()));
            }
        }
        if (insert == 1) {
            modelAndView.addObject("msg", "添加成功");
            modelAndView.setViewName("/proj/list");
            return modelAndView;
        } else {
            modelAndView.addObject("msg", "添加失败");
            modelAndView.setViewName("500");
            return modelAndView;
        }
    }

    /**
     * 查找所有类别,技术
     * @return
     */
    @GetMapping("/getCategoryByCondition")
    public ModelAndView getCategoryByCondition(ModelAndView mav) {
        List<Category> categoryList = categoryService.getCategoryByCondition();
        mav.addObject("categoryList", categoryList);

        List<Technology> technologyList=technologyService.getTechnologyByCondition();
        mav.addObject("technologyList",technologyList);
        mav.setViewName("proj/addProj1");
        return mav;
    }

    /**
     * 展示项目页面
     */
    @GetMapping("/showProject")
    public ModelAndView showProject(ModelAndView mav){
        List<CategoryDTO> categoryDTOList = projService.selectProjsByCategory(null);
        mav.addObject("categoryDTOList",categoryDTOList);
        mav.setViewName("proj/items");
        return mav;
    }
    /**
     * 展示项目页面搜索功能
     */
//    @ResponseBody
    @GetMapping("/showProjectByName")
    public ModelAndView showProjectByName(String projName,
                                          ModelAndView mav){
        List<CategoryDTO> categoryDTOList = projService.selectProjsByCategory(projName);
        mav.addObject("categoryDTOList",categoryDTOList);
        mav.setViewName("proj/items");
        return mav;
    }

    @GetMapping("/more")
    public ModelAndView more(ModelAndView mav){
        mav.setViewName("proj/more");
        return mav;
    }

    /**
     * 子查询最终版
     * @RequestParam(value = "cid",defaultValue = "4")  不传默认为4
     * @return
     */
    @GetMapping("/test/{fid}/{pageNum}/{pageSize}")
    public ModelAndView test(@PathVariable("fid") Integer fid,
                             @PathVariable("pageNum") Integer pageNum,
                             @PathVariable("pageSize") Integer pageSize,
                             @RequestParam(value = "cid",defaultValue = "") Long cid,
                             ModelAndView mav){
        // 查数据暂且写死
        List<Category> categories = categoryService.selectIdsByPid(fid.longValue());
        if (ObjectUtils.isEmpty(cid)){
            cid = categories.get(0).getId();
        }
        PageBean<ProjListItemDTO> pageBean = projService.showAll(fid, cid.intValue(),null,pageNum, pageSize);
        mav.addObject("pageBean",pageBean);
        mav.addObject("title","更多项目");
        mav.addObject("categories",categories);
        mav.setViewName("proj/more");
        return mav;
    }

    /**
     * 添加项目
     * @param xlsxPath
     * @return
     */
    @ResponseBody
    @PostMapping("/addProjs")
    public Result registUsers(@RequestParam("xlsxPath") String xlsxPath){
        xlsxPath = xlsxPath.replace("\\","\\\\");
        EasyExcel.read(xlsxPath, Proj.class, projExcelListener)
                .sheet()
                .doRead();
        return ResultUtil.success().setMsg("添加成功！");
    }

}